#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <MQTTClient.h>
  
#define ADDRESS       "tcp://192.168.23.43:1883"
#define CLIENTID      "b253ba38-daf6-4b37-984f-5d8fdc6a1cfa" 
#define TOPIC_PULL "remote_to_local"  // 订阅主题
#define TOPIC_PUSH "local_to_remote" // 发布主题
#define PAYLOAD       "Hello World!"
#define QOS             1
#define TIMEOUT       10000L

static MQTTClient_message pubmsg = MQTTClient_message_initializer;
  
void delivered(void *context, MQTTClient_deliveryToken dt)
{
      printf("Message with token value %d delivery confirmed\n", dt);
}
  
int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
      printf("Message arrived\n");
      printf("       topic: %s\n", topicName);
      printf("    message: %.*s\n", message->payloadlen, (char*)message->payload);
      MQTTClient_freeMessage(&message);
      MQTTClient_free(topicName);
      return 1;
}
  
void connlost(void *context, char *cause)
{
      printf("\nConnection lost\n");
      printf("       cause: %s\n", cause);
}
  
int main(int argc, char* argv[])
{
      MQTTClient client;
      MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
      int rc;
  
      if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID,
            MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS)
      {
            printf("Failed to create client, return code %d\n", rc);
            rc = EXIT_FAILURE;
            goto exit;
      }
  
      if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS)
      {
            printf("Failed to set callbacks, return code %d\n", rc);
            rc = EXIT_FAILURE;
            goto destroy_exit;
      }
  
      if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
      {
            printf("Failed to connect, return code %d\n", rc);
            rc = EXIT_FAILURE;
            goto destroy_exit;
      }
  
      printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
                 "Press Q<Enter> to quit\n\n", TOPIC_PULL, CLIENTID, QOS);
      if ((rc = MQTTClient_subscribe(client, TOPIC_PULL, QOS)) != MQTTCLIENT_SUCCESS)
      {
            printf("Failed to subscribe, return code %d\n", rc);
            rc = EXIT_FAILURE;
      }
      else
      {
            int ch;
            do
            {
                        ch = getchar();
            } while (ch!='Q' && ch != 'q');
  
            if ((rc = MQTTClient_unsubscribe(client, TOPIC_PULL)) != MQTTCLIENT_SUCCESS)
            {
                        printf("Failed to unsubscribe, return code %d\n", rc);
                        rc = EXIT_FAILURE;
            }
}

      pubmsg.payload = PAYLOAD;
      pubmsg.payloadlen = (int)strlen(PAYLOAD);
      pubmsg.qos = QOS;
      if ((rc = MQTTClient_publishMessage(client, TOPIC_PUSH, &pubmsg, NULL)) != MQTTCLIENT_SUCCESS)
      {
            printf("Failed to publish message, return code %d\n", rc);
            rc = EXIT_FAILURE;
      }
  
      if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS)
      {
            printf("Failed to disconnect, return code %d\n", rc);
            rc = EXIT_FAILURE;
}
return rc;

destroy_exit:
      MQTTClient_destroy(&client);
exit:
      return rc;
}